home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
pctecap.arc
/
DSCOPE1.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-03-15
|
6KB
|
191 lines
;
; Program DSCOPE1
; copyright (C) 1983 Peter G. Aitken
; Department of Physiology
; Duke University Medical Center, Durham, NC 27710
;
; This program collects and averages sweeps of analog data from
; channel 0 of the labmaster board, with each sweep triggered
; by a pulse on channel 7. It requires that the calling program set
; up clock 5 to output pulses at the desired sampling rate, and
; that the Labmaster be jumpered for external start a/d conversions.
; The calling program must also pass two parameters: the address of the
; array for data storage, and the number of sweeps to be averaged.
; Program now collects 640 points/sweep. Subroutine "beep" beeps the
; speaker after each sweep. Maximum sampling rate=40kHz.
;
sseg segment stack ;set up stack.
dw 20 DUP (?)
sseg ends
;
dseg segment ;set up data segment.
array dw (?)
nswps dw (?)
dseg ends
;
cseg segment public 'CODE' ;code segment.
;
assume cs:cseg,ss:sseg,ds:dseg
;
public dscope1 ;declare "dscope1" public so it can
;be called from another program.
dscope1 proc far
push bp ;save register.
mov bp,sp
mov si,[bp]+8 ;get first parameter passed by
;calling program.
mov dx,[si]
mov array,dx ;data array address in "array".
mov si,[bp]+6 ;get second parameter passed.
mov dx,[si]
mov nswps,dx ;# sweeps in nswps.
inc nswps ;now nswps=#sweeps+1.
;
;now we go thru the array and zero all elements.
;
mov bx,array ;bx points at base of array.
mov si,0 ;si indexes array element.
mov cx,640 ;cx counts array elements.
mov ax,0
zero_loop: mov [bx][si],ax ;move "0" to array element.
add si,2 ;point at next element.
loop zero_loop ;loop back if cx<>0.
;
;now we wait for a synch pulse on a/d channel 7.
;
synch_loop: nop
dec nswps ;nswps now = # sweeps remaining.
jz done ;if it's 0, we're done.
;
wait_synch: mov dx,0714H ;point at control byte.
mov al,10000000B ;disable autoincrement and
out dx,al ;all interrupts.
inc dx ;point at a/d channel byte and
mov al,7 ;specify that next channel
out dx,al ;to convert is #7.
inc dx ;point at a/d start & hi data.
in al,dx ;read high data to reset
;done bit.
out dx,al ;start a conversion.
mov dx,0714H ;point dx at status byte
wait_done: in al,dx ;and read it in.
cmp al,10000000B ;see if bit 7 is set.
jb wait_done ;if not, look again.
inc dx ;point at low data byte.
in ax,dx ;read ch#7 voltage.
cmp ax,1024 ;is it > "1024"?
jl wait_synch ;if not, try again.
;
;now that a synch pulse has been received, we can collect data
;
get_data: mov cx,640 ;cx will count loops.
mov si,0 ;si=array offset pointer.
mov bx,array ;bx=array base pointer.
mov dx,0714H ;point at control byte.
mov al,10000100B ;enable external starts and
out dx,al ;disable autoincrementing.
inc dx ;point dx at 0715H.
in ax,dx ;read data to clear "done"bit.
mov al,0
out dx,al ;specify a/d channel #0.
data_loop: dec dx ;point at status byte
in_loop: in al,dx ;and get it.
cmp al,10000000B ;is bit 7 set?
jb in_loop ;no, try again.
inc dx ;point at 0715h.
in ax,dx ;get data word and
add [bx][si],ax ;add it to array.
add si,2 ;point si at next array element.
loop data_loop ;and loop back if 640 pts haven't
;been collected, i.e., if cx>0.
dec dx ;point at control byte.
mov al,10000000B ;disable autostart.
out dx,al
;
call beep ;beep speaker.
;
;put "x" plus 2 spaces on screen to indicate sweep.
;
push ax ;save registers.
push bx
push bp
mov bh,0 ;select display page.
mov al,120 ;character "x".
mov ah,14 ;write, advance cursor.
int 10H
mov ah,14
mov al,32 ;character " ".
int 10H
mov ah,14
mov al,32 ;character " ".
int 10H
pop bp ;restore registers.
pop bx
pop ax
;
jmp synch_loop ;go wait for another pulse.
;
done: nop
;
;now go back thru array dividing by # sweeps.
;
mov si,[bp]+6
mov dx,[si] ;now dx has # sweeps.
mov nswps,dx ;now nswps has # sweeps.
mov si,0
mov cx,640 ;cx will count loops.
div_loop: mov ax,[bx][si] ;move array element to ax.
cwd ;convert to dbl word.
idiv nswps ;divide by # sweeps.
mov [bx][si],ax ;put quotient back in array.
add si,2 ;point at next array element.
loop div_loop ;loop back if all not done.
;
pop bp ;restore bp.
sti
ret 4
dscope1 endp
;
;this subroutine "beep" plays a tone on the speaker - desired duration
;(in milliseconds) and frequency (in Hz) are placed in bx
;and di, respectively.
;
beep proc
push ax ;save registers.
push bx
push cx
push dx
push di
mov di,500 ;set frequency.
mov bx,50 ;set duration to 50 msec.
mov al,0B6H ;write control byte to timer mode reg.
out 43H,al
mov dx,14H ;to get desired freq, we must send
mov ax,4F38H ;the value 1331000/freq to timer 2.
div di
out 42H,al ;write low byte to timer 2.
mov al,ah
out 42H,al ;write high byte to timer 2.
in al,61H ;get current timer port setting.
mov ah,al ;save it in ah.
or al,3 ;change bits 0 and 1 and send to timer
out 61H,al ;port, which turns speaker on.
hold_it: mov cx,280 ;wait 1 msec.
beeping: loop beeping ;this loop cycles 280 times in one
;msec.
dec bx ;has the count expired?
jnz hold_it ;if not, go back for another msec.
mov al,ah ;recover port value.
out 61H,al ;speaker off.
pop di ;restore reg.
pop dx
pop cx
pop bx
pop ax
ret
beep endp
;
cseg ends
end
;